package org.hxzon.tapestry5.components;

import java.util.List;

import org.apache.tapestry5.BindingConstants;
import org.apache.tapestry5.MarkupWriter;
import org.apache.tapestry5.annotations.AfterRender;
import org.apache.tapestry5.annotations.BeginRender;
import org.apache.tapestry5.annotations.Parameter;
import org.apache.tapestry5.internal.TapestryInternalUtils;
import org.apache.tapestry5.ioc.annotations.Inject;
import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
import org.apache.tapestry5.services.Request;
import org.hxzon.tapestry5.components.base.AbstractFieldEx;
import org.hxzon.tapestry5.model.ValueLabel;
import org.hxzon.tapestry5.util.TapestryEx;

public class RadioGroupEx extends AbstractFieldEx {

    @Parameter(name = "value")
    private Object _value;

    @Parameter(name = "source", required = true, allowNull = false)
    private List<Object> _source;

    //when value not null,select value;
    //when select=-1,select null;else,select select
    @Parameter(name = "select", value = "0")
    private int _select;

    @Parameter(name = "valueLabel")
    private ValueLabel<Object> _valueLabel;

    @Parameter(name = "readonly", value = "false")
    private boolean _readonly;

    @Parameter(name = "labelFirst", value = "false")
    private boolean _labelFirst;

    @Parameter(name = "class", defaultPrefix = BindingConstants.LITERAL)
    private String _itemClass;

    @Inject
    private Request _request;

    @BeginRender
    void begin(MarkupWriter writer) {
        writeTitle(writer);
        //
        String ctrlName = getControlName();
        String clientId = getClientId();
        if (_select == -1) {
            writeRadio(writer, (clientId + "__1"), ctrlName, (this._value == null), -1, "不选", _labelFirst, _itemClass);
        }
        int size = _source.size();
        for (int i = 0; i < size; i++) {
            String label = null;
            Object curValue = _source.get(i);

            if (_valueLabel != null) {
                label = _valueLabel.toLabel(curValue, i);
            } else {
                label = curValue.toString();
            }

            boolean checked = this._value == curValue;
            if (this._value == null && _select == i) {
                checked = true;
            }
            writeRadio(writer, (clientId + "_" + i), ctrlName, checked, i, label, _labelFirst, _itemClass);
        }// end for

    }

    private void writeRadio(MarkupWriter writer, String clientId, String ctrlName, boolean checked, int index, String label, boolean labelFirst, String itemClass) {
        //boolean drawItem = itemClass != null;
        boolean drawItem = true;
        if (drawItem) {
            writer.element("span", "class", buildItemClass(itemClass, checked));
        }
        if (labelFirst) {
            writer.element("label", "for", clientId);
            writer.write(label);
            writer.end();
        }
        writer.element("input", "type", "radio", "name", ctrlName, "id", clientId, "checked", checked ? "checked" : null, "value", index, "disabled", _readonly ? "disabled" : null);
        writer.end();
        if (!labelFirst) {
            writer.element("label", "for", clientId);
            writer.write(label);
            writer.end();
        }
        if (drawItem) {
            writer.end();
        }
    }

    private String buildItemClass(String itemClass, boolean checked) {
        List<String> classes = CollectionFactory.newList();

        if (itemClass != null) {
            classes.add(itemClass);
        }
        if (checked) {
            classes.add(TapestryEx.Css_CheckboxOrigChecked);
        }
        return TapestryInternalUtils.toClassAttributeValue(classes);
    }

    @AfterRender
    void after(MarkupWriter writer) {

    }

    @Override
    protected void processSubmission(String controlName) {

        String[] postedValues = _request.getParameters(controlName);
        if (postedValues == null || postedValues.length == 0) {
            _value = null;
            return;
        }
        int postedValue = Integer.valueOf(postedValues[0]);
        if (postedValue == -1) {
            _value = null;
        } else {
            _value = _source.get(postedValue);
        }
    }
}